package com.jahe.learn.netty4.websocket;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.util.CharsetUtil;

/**
 * websocket的握手和协议升级的http协议的处理器
 * @author: jahe.lai
 * @create: 2019-12-27 17:49
 */
public class WSClientShakeHandler extends SimpleChannelInboundHandler<HttpObject> {

    private WebSocketClientHandshaker handshaker;
    private ChannelPromise handshakeFuture;

    public WebSocketClientHandshaker getHandshaker() {
        return handshaker;
    }

    public void setHandshaker(WebSocketClientHandshaker handshaker) {
        this.handshaker = handshaker;
    }

    public ChannelPromise getHandshakeFuture() {
        return handshakeFuture;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        this.handshakeFuture = ctx.newPromise();
        System.out.println("WSClientShakeHandler-----channelActive "+ ctx.channel().isActive());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("WSClientShakeHandler-----msg= "+msg.getClass());
        if (!getHandshaker().isHandshakeComplete()) {
            FullHttpResponse response = (FullHttpResponse)msg;
            //握手协议返回，设置结束握手
            this.handshaker.finishHandshake(channel, response);
            //设置成功
            this.handshakeFuture.setSuccess();
        } else if (msg instanceof FullHttpResponse) {
            //1.第一次握手请求消息由HTTP协议承载，所以它是一个HTTP消息，执行handleHttpRequest方法来处理WebSocket握手请求。
            FullHttpResponse response = (FullHttpResponse)msg;
            throw new IllegalStateException("Unexpected FullHttpResponse (getStatus=" + response.status() + ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');
        }
        System.out.println("ERROR WSClientShakeHandler-----msg= "+msg.getClass());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (!handshakeFuture.isDone()) {
            handshakeFuture.setFailure(cause);
        }
        ctx.close();
    }
}
